//build: 20250513
import { faceClass } from './libvbar-b-dxface.so'
import dxCommon from './dxCommon.js'
import bus from './dxEventBus.js'
const faceObj = new faceClass();
const face = {}

/**
 * Face processing initialization
 * @param {object} options Most configuration parameters can use the default values.
 * @param {string} options.rgbPath Required: Path to the RGB image acquisition device. This path varies depending on the device;
 * @param {string} options.nirPath Required field: Path to the infrared image acquisition device. This path varies depending on the device.
 * @param {string} options.dbPath Database path (required)
 * @param {number} options.score Minimum comparison score required for successful feature value comparison (optional, default 0.6)
 * @param {number} options.dbMax The maximum number of feature lists that can be loaded into memory. Optional (default 5000).
 * @param {string} options.mapPath Calibration result file path (optional)
 * @param {string} options.picPath Save the complete path to the face photo (optional)
 * @param {string} capturerRgbId Required, RGB image handle ID
 * @param {string} capturerNirId Required, .nir image handle ID
 * @returns true/false
 */
face.init = function (options, capturerRgbId, capturerNirId) {
	if (options.rgbPath === undefined || options.rgbPath === null || options.rgbPath.length < 1) {
		throw new Error("dxFace.init: 'rgbPath' parameter should not be null or empty")
	}
	if (options.nirPath === undefined || options.nirPath === null || options.nirPath.length < 1) {
		throw new Error("dxFace.init: 'nirPath' parameter should not be null or empty")
	}
	if (capturerRgbId === undefined || capturerRgbId === null || capturerRgbId.length < 1) {
		throw new Error("dxFace.init: 'capturerRgbId' parameter should not be null or empty")
	}
	if (capturerNirId === undefined || capturerNirId === null || capturerNirId.length < 1) {
		throw new Error("dxFace.init: 'capturerNirId' parameter should not be null or empty")
	}
	capturerRgbId = dxCommon.handleId("capturer", capturerRgbId)
	capturerNirId = dxCommon.handleId("capturer", capturerNirId)

	return faceObj.init(options, capturerRgbId, capturerNirId);
}
/**
 * Face processing deinitialization
 * @returns true/false
 */
face.deinit = function () {
	return faceObj.deinit();
}

/**
 * Face recognition working mode
 * @param {number} mode Working mode (required): (0 for face recognition mode; 1 for face registration mode)
 * @returns true/false
 */
face.setRecgMode = function (mode) {
	if (mode === undefined || mode === null) {
		throw new Error("dxFace.setRecgMode: 'mode' parameter should not be null or empty")
	}
	return faceObj.setRecgMode(mode)
}
/**
 * Face registration
 * @param {string} userId 	Personnel ID (required)
 * @param {string} feature 	Feature value (base64 string, required)
 * @returns 0: Success / Non-zero: Failure
 */
face.addFaceFeatures = function (userId, feature) {
	if (userId === undefined || userId === null) {
		throw new Error("dxFace.addFaceFeatures: 'userId' parameter should not be null or empty")
	}
	if (feature === undefined || feature === null) {
		throw new Error("dxFace.addFaceFeatures: 'feature' parameter should not be null or empty")
	}

	return faceObj.addFaceFeatures(userId, feature)
}
/**
 * Facial feature value comparison
 * @param {string} feature 	Feature value (base64 string, required)
 * @param {string} score 	The comparison threshold is optional; the default value is 0.6.
 * @returns string userId
 */
face.faceFeatureCompare = function (feature, score) {
	if (feature === undefined || feature === null) {
		throw new Error("dxFace.faceFeatureCompare: 'feature' parameter should not be null or empty")
	}
	return faceObj.faceFeatureCompare(feature, score)
}
/**
 * Update configuration
 * @param {object} options Registration parameters are obtained from the registration callback; refer to the `face.addFaceFeatures` method.
 * @returns true/false
 */
face.faceUpdateConfig = function (options) {
	if (options === null || options === undefined) {
		throw new Error("dxFace.faceUpdateConfig: 'options' parameter should not be null or empty")
	}
	return faceObj.faceUpdateConfig(options)
}
/**
 * Face deletion
 * @param {string} userId Personnel ID (required)
 * @returns true/false
 */
face.deleteFaceFeatures = function (userId) {
	if (userId === null || userId === undefined) {
		throw new Error("dxFace.deleteFaceFeatures: 'userId' parameter should not be null or empty")
	}
	return faceObj.deleteFaceFeatures(userId)
}
/**
 * Register face based on photo path and userId
 * @param {string} userId 	User ID (required)
 * @param {string} picPath	Photo path (required)
 * @returns true/false
 */
face.registerFaceByPicFile = function (userId, picPath) {
	if (userId === undefined || userId === null || userId.length < 1) {
		throw new Error("dxFace.registerFaceByPicFile: 'userId' parameter should not be null or empty")
	}
	if (picPath === undefined || picPath === null || picPath.length < 1) {
		throw new Error("dxFace.registerFaceByPicFile: 'picPath' parameter should not be null or empty")
	}
	return faceObj.registerFaceByPicFile(userId, picPath)
}
/**
 * Face recognition thread enabled/disabled, function switch
 * @param {bool} en Enable/Disable (Required)
 * @returns true/false
 */
face.faceSetEnable = function (en) {
	if (en === undefined || en === null) {
		throw new Error("dxFace.faceSetEnable: 'en' parameter should not be null or empty")
	}
	return faceObj.detectSetEnable(en ? 0 : -1)
}

/**
 * Reset face status
 * @returns 
 */
face.resetFaceStatus = function () {
	return faceObj.resetFaceStatus()
}

/**
 * Clear facial data
 * @returns true/false
 */
face.faceFeaturesClean = function () {
	return faceObj.faceFeaturesClean()
}

/**
 * Get screen brightness
 * @returns number Screen brightness
 */
face.getDisplayBacklight = function () {
	return faceObj.getDisplayBacklight()
}
/**
 * Set screen brightness
 * @param {number} light Screen brightness (required)
 * @returns true/false
 */
face.setDisplayBacklight = function (light) {
	if (light === undefined || light === null) {
		throw new Error("dxFace.setDisplayBacklight: 'light' parameter should not be null or empty")
	}
	return faceObj.setDisplayBacklight(light)
}
/**
 * Get screen status
 * @returns number 0 - Disabled 1 - Enabled
 */
face.getEnableStatus = function () {
	return faceObj.getEnableStatus()
}
/**
 * Set screen status
 * @param {number} enable 0 - Disabled 1 - Enabled
 * @returns true/false
 */
face.setEnableStatus = function (enable) {
	if (enable === undefined || enable === null) {
		throw new Error("dxFace.setEnableStatus: 'enable' parameter should not be null or empty")
	}
	return faceObj.setEnableStatus(enable)
}
/**
/**
 * Get screen status
 * @returns number 0-NORMAL 1-STANDBY
 */
face.getPowerMode = function () {
	return faceObj.getPowerMode()
}
/**
 * Set screen status
 * @param {number} mode 0-NORMAL 1-STANDBY
 * @returns true/false
 */
face.setPowerMode = function (mode) {
	if (mode === undefined || mode === null) {
		throw new Error("dxFace.setPowerMode: 'mode' parameter should not be null or empty")
	}
	return faceObj.setPowerMode(mode)
}
/**
 * Acquire ambient light
 * @returns number Ambient light
 */
face.getEnvBrightness = function () {
	return faceObj.getEnvBrightness()
}
/**
 * Obtain face coordinates
 * @returns string Face coordinates JSON
 */
face.getTrackingBox = function () {
	return faceObj.getTrackingBox()
}
/**
 * Query total number of users
 * @returns number
 */
face.selectCount = function () {
	return faceObj.selectFaceFeatures(1)
}
/**
 * Query all userIds
 * @returns JSON
 */
face.selectAll = function () {
	return faceObj.selectFaceFeatures(2)
}
/**
 * Determine if the user exists
 * @returns true/false
 */
face.userExist = function (userId) {
	return faceObj.selectFaceFeatures(3, userId)
}
/**
 * Check if the face message queue is empty.
 * @returns true/false
 */
face.msgIsEmpty = function () {
	return faceObj.msgIsEmpty()
}
/**
 * Read data from the face message queue.
 * @returns json
 */
face.msgReceive = function () {
	return JSON.parse(faceObj.msgReceive());
}

face.RECEIVE_MSG = '__face__MsgReceive'

/**
 * To simplify the use of the micro-light communication protocol for the Face component, the Face component is encapsulated within this worker. Users only need to subscribe to eventbus events to listen to the Face component.
 */
face.run = function () {
	let workerFile = '/app/code/dxmodules/faceWorker.js'
	bus.newWorker('__face', workerFile)
}

/**
 * If `face` is a separate thread, you can directly use the `run` function, which will automatically start a thread.
 * If you want to join another existing thread, you can use the following encapsulated function.
 */
face.worker = {
	//Before the while loop
	beforeLoop: function (options) {
		// Face algorithm initialization
		face.init(options, options.capturerRgbId, options.capturerNirId)
	},
	//In a while loop
	loop: function () {
		if (!face.msgIsEmpty()) {
			let res = face.msgReceive();
			bus.fire(face.RECEIVE_MSG, res)
		}
	}
}

export default face;
